package com.taxshare.seller.service;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.taxshare.mybatis.pager.PageHelp;
import com.taxshare.mybatis.pager.PageRequest;
import com.taxshare.mybatis.utils.DozerBeanUtil;
import com.taxshare.response.beans.Response;
import com.taxshare.seller.constant.CodeConstant;
import com.taxshare.seller.entity.*;
import com.taxshare.seller.mapper.*;
import com.taxshare.seller.remote.ApiClientService;
import com.taxshare.seller.util.TransformationUtil;
import com.taxshare.seller.view.dto.CancelInvoiceDTO;
import com.taxshare.seller.view.dto.DocumentInfoDTO;
import com.taxshare.seller.view.dto.RedInvoiceInfoFirstDTO;
import com.taxshare.seller.view.vo.DocumentInfoReqVO;
import com.taxshare.seller.view.vo.RedTicketOperateReqVO;
import com.taxshare.seller.view.vo.SellerInvoiceRVO;
import com.taxshare.tools.token.UserInfoUtil;
import com.taxshare.tools.util.Arith;
import com.taxshare.tools.util.DateUtil;
import com.taxshare.tools.util.StringUtil;
import com.taxshare.tools.util.UUIDUitl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author YANG
 * @date 2021/5/17
 * @Description:同步明源单据信息
 */
@Service
@Slf4j
public class DocumentInfoService extends ServiceImpl<DocumentInfoMapper, DocumentInfoEntity> {

    @Value("${mingyuan.url}")
    private String mingyuanUrl;

    @Autowired
    DocumentInfoDetailMapper documentInfoDetailMapper;

    @Autowired
    CancelDocDetailMapper cancelDocDetailMapper;

    @Autowired
    InvoicedService invoicedService;

    @Autowired
    SellerInvoiceRuleService sellerInvoiceRuleService;//开票规则

    @Autowired
    GoodsManageService goodsManageService; //商品

    @Autowired
    InvoicedMapper invoicedMapper;

    @Autowired
    InvoiceDetailService invoiceDetailService;

    @Autowired
    ApiClientService apiClientService;

    @Autowired
    ProjectInfoMapper projectInfoMapper;

    @Autowired
    RedTicketService redTicketService;

    @Autowired
    AsyncDocumentService asyncDocumentService;


    /**
     * 同步明源单据信息
     *
     * @param documentInfoDTO
     * @return
     */
    public Response syncDocument(DocumentInfoDTO documentInfoDTO) {
        DocumentInfoEntity docMain = documentInfoDTO.getDocMain();
        QueryWrapper queryOrganization = new QueryWrapper();
        queryOrganization.eq("company_name", docMain.getSellerName());
        queryOrganization.eq("company_tax_number", docMain.getSellerTaxNo());
        List list = baseMapper.queryOrganization(queryOrganization);
        if (CollectionUtils.isEmpty(list)) {
            return Response.error("SEL_SYNC_005");
        }
        List<DocumentInfoDetailEntity> docDetail = documentInfoDTO.getDocDetail();
        if (docMain != null) {
            QueryWrapper<SellerInvoiceEntity> invoicdQuery = new QueryWrapper<>();
            invoicdQuery.eq("make_invoice_state", CodeConstant.YK);
            invoicdQuery.eq("doc_id", docMain.getDocId());
            if (invoicedMapper.selectCount(invoicdQuery) > 0) {
                return Response.success(mingyuanUrl + docMain.getDocId());
            }
            docMain.setInvoiceType(TransformationUtil.documentInvoiceType(docMain.getInvoiceType()));
            docMain.setAmountWithoutTax((new BigDecimal(docMain.getAmountWithoutTax()).setScale(2, RoundingMode.HALF_UP)).doubleValue());
            docMain.setAmountWithTax((new BigDecimal(docMain.getAmountWithTax()).setScale(2, RoundingMode.HALF_UP)).doubleValue());
            docMain.setTaxAmount((new BigDecimal(docMain.getTaxAmount()).setScale(2, RoundingMode.HALF_UP)).toString());
            QueryWrapper<DocumentInfoEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("doc_id", docMain.getDocId());
            if (baseMapper.selectCount(queryWrapper) > 0) {
                baseMapper.update(docMain, queryWrapper);
            } else {
                docMain.setUuid(UUIDUitl.UUID32(false));
                //特殊处理（明源传输的开票人、复核人、收款人数据一样）
                docMain.setAuditor("");
                baseMapper.insert(docMain);
            }
        } else {
            return Response.error("SEL_SYNC_001");
        }
        if (docDetail != null) {
            QueryWrapper<DocumentInfoDetailEntity> detailQuery = new QueryWrapper<>();
            detailQuery.eq("doc_id", docMain.getDocId());
            if (documentInfoDetailMapper.selectCount(detailQuery) > 0) {
                documentInfoDetailMapper.delete(detailQuery);
            }
            for (DocumentInfoDetailEntity documentInfoDetailEntity : docDetail) {
                String taxRateFlag = documentInfoDetailEntity.getTaxRateFlag();
                documentInfoDetailEntity.setUuid(UUIDUitl.UUID32(false));
                double taxRate = documentInfoDetailEntity.getTaxRate();
                documentInfoDetailEntity.setTaxRate(NumberUtil.div(taxRate, 100));
                documentInfoDetailEntity.setAmountWithoutTax((new BigDecimal(documentInfoDetailEntity.getAmountWithoutTax()).setScale(2, RoundingMode.HALF_UP)).doubleValue());
                documentInfoDetailEntity.setAmountWithTax((new BigDecimal(documentInfoDetailEntity.getAmountWithTax()).setScale(2, RoundingMode.HALF_UP)).doubleValue());
                String pattern = ".*[*].*";
                boolean isMatch = Pattern.matches(pattern, documentInfoDetailEntity.getTaxAmount());
                if(isMatch){
                    documentInfoDetailEntity.setTaxAmount("0");
                }
                if (CodeConstant.BZS.equals(taxRateFlag)) {
                    documentInfoDetailEntity.setTaxAmount(documentInfoDetailEntity.getTaxAmount());
                    documentInfoDetailEntity.setTaxRate(Double.parseDouble("0"));
                } else if (CodeConstant.PTLSL.equals(taxRateFlag)) {
                    documentInfoDetailEntity.setTaxRate(Double.parseDouble("0"));
                } else {
                    documentInfoDetailEntity.setTaxAmount((new BigDecimal(documentInfoDetailEntity.getTaxAmount()).setScale(2, RoundingMode.HALF_UP)).toString());
                }
                documentInfoDetailMapper.insert(documentInfoDetailEntity);
            }
        }
        String loginUrl = mingyuanUrl + docMain.getDocId()+"&timestamp="+System.currentTimeMillis();
        return Response.success(loginUrl);
    }


    /**
     * 订单列表
     *
     * @param query
     * @return
     */
    public Response<IPage<DocumentInfoEntity>> queryDocument(PageRequest<DocumentInfoReqVO> query) {
        QueryWrapper<DocumentInfoEntity> queryWrapper = new QueryWrapper<>();
        DocumentInfoReqVO documentInfoReqVO = query.getInfo();
        if (StrUtil.isNotBlank(documentInfoReqVO.getDocId())) {
            queryWrapper.eq("doc_id", documentInfoReqVO.getDocId());
        }
        if (StrUtil.isNotBlank(documentInfoReqVO.getSellerName())) {
            queryWrapper.like("seller_name", documentInfoReqVO.getSellerName());
        }
        if (StrUtil.isNotBlank(documentInfoReqVO.getSellerTaxNo())) {
            queryWrapper.eq("seller_tax_no", documentInfoReqVO.getSellerTaxNo());
        }
        if (StrUtil.isNotBlank(documentInfoReqVO.getPurchaserName())) {
            queryWrapper.like("purchaser_name", documentInfoReqVO.getPurchaserName());
        }
        if (StrUtil.isNotBlank(documentInfoReqVO.getPurchaserTaxNo())) {
            queryWrapper.eq("purchaser_tax_no", documentInfoReqVO.getPurchaserTaxNo());
        }
        if (StrUtil.isNotBlank(documentInfoReqVO.getOrderState())) {
            queryWrapper.eq("order_state", documentInfoReqVO.getOrderState());
        }
        queryWrapper.orderByDesc("create_time");
        IPage<DocumentInfoEntity> documentInfoEntityIPage = PageHelp.siamplePage(this, queryWrapper, query.getPage(), DocumentInfoEntity.class);
        return Response.success(documentInfoEntityIPage);
    }

    /**
     * 订单明细查询
     *
     * @param docId
     * @return
     */
    public Response<List<DocumentInfoDetailEntity>> queryDetail(String docId) {
        QueryWrapper<DocumentInfoDetailEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("doc_id", docId);
        List<DocumentInfoDetailEntity> list = documentInfoDetailMapper.selectList(queryWrapper);
        return Response.success(list);
    }

    public Response makeInvoice(List idList) {
        Response res = new Response();
        QueryWrapper<DocumentInfoEntity> queryWrapper = new QueryWrapper<DocumentInfoEntity>();
        queryWrapper.in("doc_id", idList);
        queryWrapper.groupBy("seller_tax_no");
        List<DocumentInfoEntity> documentList = this.list(queryWrapper);
        String userid = UserInfoUtil.getUserID();
        if (documentList.size() == 0) {
            res.setMsg("无销方税号信息！");
            res.setCode("T0001");
        } else {
            String msgStr = "税号:";
            for (int i = 0; i < documentList.size(); i++) {
                DocumentInfoEntity docinfo = documentList.get(i);
                String sellerTaxNo = docinfo.getSellerTaxNo();
                if (!sellerTaxNo.equals("")) {
                    List<SellerInvoiceRuleEntity> sellerInvoiceRuleEntityList = sellerInvoiceRuleService.list(new QueryWrapper<SellerInvoiceRuleEntity>().eq("seller_tax_no", sellerTaxNo).eq("disable", "1"));
                    if (sellerInvoiceRuleEntityList == null) {
                        msgStr += sellerTaxNo;
                        break;
                    }
                } else {
                    return Response.error("T0001", "销方税号不能为空！");
                }

            }

            if (!msgStr.equals("税号:")) {
                res.setCode("T0001");
                res.setMsg(msgStr + " 没有维护或开启开票规则,设备！");
            } else {
                for (int i = 0; i < documentList.size(); i++) {
                    DocumentInfoEntity docinfo = documentList.get(i);
                    String sellerTaxNo = docinfo.getSellerTaxNo();
                    List<SellerInvoiceRuleEntity> sellerInvoiceRuleEntityList = sellerInvoiceRuleService.list(new QueryWrapper<SellerInvoiceRuleEntity>().eq("seller_tax_no", sellerTaxNo).eq("disable", "1"));
                    SellerInvoiceRuleEntity sellerInvoiceRuleEntity = null;
                    if (sellerInvoiceRuleEntityList != null && !sellerInvoiceRuleEntityList.isEmpty()) {
                        sellerInvoiceRuleEntity = sellerInvoiceRuleEntityList.get(0);
                    }
                    res = makeInvoiceType(sellerInvoiceRuleEntity, idList);
                }
            }
        }
        return res;
    }

    public Response makeInvoiceType(SellerInvoiceRuleEntity sellerInvoiceRuleEntity, List idList) {
        Response res = new Response();
        QueryWrapper<DocumentInfoEntity> queryWrapper = new QueryWrapper<DocumentInfoEntity>();
        queryWrapper.in("doc_id", idList);
        queryWrapper.orderByDesc();
        List<DocumentInfoEntity> orderEntityList = this.list(queryWrapper);

        for (int i = 0; i < orderEntityList.size(); i++) {
            DocumentInfoEntity sellerOrderEntity = orderEntityList.get(i);
            String orderState = sellerOrderEntity.getOrderState();
            if ("1".equals(orderState)) {
                break;
            }
            String id = sellerOrderEntity.getUuid();
            List<DocumentInfoDetailEntity> sellerOrderDetailEntityList = documentInfoDetailMapper.selectList(new QueryWrapper<DocumentInfoDetailEntity>().eq("doc_id", sellerOrderEntity.getDocId()));
            String checkRecordNo = sellerOrderEntity.getDocId();
            List list = dataProcessing(sellerInvoiceRuleEntity, sellerOrderDetailEntityList, sellerOrderEntity, checkRecordNo);
            insertIntoInvoiceTable(list);
            //修改状态
            sellerOrderEntity.setOrderState("1");
            this.updateById(sellerOrderEntity);
        }
        return res;
    }

    /**
     * @param sellerInvoiceRuleEntity 规则
     * @param orderDetailList         订单明细
     * @param sellerOrderEntity       订单
     * @param checkRecordNo           docId
     * @return
     */
    public List dataProcessing(SellerInvoiceRuleEntity sellerInvoiceRuleEntity, List orderDetailList, DocumentInfoEntity sellerOrderEntity, String checkRecordNo) {

        String invoiceType = sellerOrderEntity.getInvoiceType();
        String mergeGoodName = sellerInvoiceRuleEntity.getMergeGoodName();
        String mergeGoodType = sellerInvoiceRuleEntity.getMergeGoodType();
        String specialInvoiceSum = sellerInvoiceRuleEntity.getSpecialInvoiceSum();
        String commonInvoiceSum = sellerInvoiceRuleEntity.getCommonInvoiceSum();
        String eleInvoiceSum = sellerInvoiceRuleEntity.getEleInvoiceSum();
        String mergeUnitPrice = sellerInvoiceRuleEntity.getMergeUnitPrice();
        String mergeUnit = sellerInvoiceRuleEntity.getMergeUnit();

        System.out.println("预开票数据加工  开始" + new Date());
        double maxInvoiceMoeny = 0;
        // 从规则获取限额
        if (invoiceType.equals("004")) {
            maxInvoiceMoeny = Double.parseDouble(specialInvoiceSum);
        } else if (invoiceType.equals("007")) {
            maxInvoiceMoeny = Double.parseDouble(commonInvoiceSum);
        } else if (invoiceType.equals("026")) {
            maxInvoiceMoeny = Double.parseDouble(eleInvoiceSum);
        }
        //明细行
        int maxRowNumber = 8;
        if (invoiceType.equals("026")) {
            maxRowNumber = 98;
        } else {
            maxRowNumber = 1598;
        }

        List<DocumentInfoDetailEntity> orderList = createOrdList("0", mergeGoodName, mergeGoodType, mergeUnit, mergeUnitPrice, orderDetailList);

        return getInvoiceList(orderList, sellerInvoiceRuleEntity, sellerOrderEntity, maxRowNumber, maxInvoiceMoeny, checkRecordNo);
    }


    /**
     * @param orderList               订单明细
     * @param sellerInvoiceRuleEntity 开票规则
     * @param sellerOrderEntity       订单
     * @param maxRowNumber            明细行
     * @param maxInvoiceMoeny         开票限额
     * @param checkRecordNo           docId
     * @return
     */
    private List getInvoiceList(List<DocumentInfoDetailEntity> orderList, SellerInvoiceRuleEntity sellerInvoiceRuleEntity,
                                DocumentInfoEntity sellerOrderEntity, int maxRowNumber, double maxInvoiceMoeny, String checkRecordNo) {
        List invoiceList = new ArrayList();
        String sellerTaxno = sellerOrderEntity.getSellerTaxNo();
        String sellerName = sellerOrderEntity.getSellerName();
        String sellerBank = sellerOrderEntity.getSellerBank();
        String sellerAddrTel = sellerOrderEntity.getSellerTelAddress();
        String buyerTaxno = sellerOrderEntity.getPurchaserTaxNo();
        String buyerName = sellerOrderEntity.getPurchaserName();
        String buyerBank = sellerOrderEntity.getPurchaserBank();
        String buyerAddrTel = sellerOrderEntity.getPurchaserTelAddress();
        String invoiceType = sellerOrderEntity.getInvoiceType();
        String remark = sellerOrderEntity.getRemark();
        String baseUintNum = sellerInvoiceRuleEntity.getBaseUintNum();//拆分规则:单价数量 等于1是以数量 其它则是单价
        String baseSumTax = sellerInvoiceRuleEntity.getBaseSumTax();//等于0含税  其他则不含税

        for (int i = 0; i < orderList.size(); i++) {
            Map mapOrder = (Map) orderList.get(i);
            List<DocumentInfoDetailEntity> details = (List<DocumentInfoDetailEntity>) mapOrder.get("data");
            String isZF = mapOrder.get("flag").toString();
            double hsjeSum = 0;
            double wsjeSum = 0;
            double seSum = 0;
            double zkhsjeSum = 0;
            double zkwsjeSum = 0;
            double zkseSum = 0;
            double spslSum = 0;
            double pmhsje = 0;
            double pmwsje = 0;
            double pmse = 0;
            double pmzkhsje = 0;
            double pmzkwsje = 0;
            double pmzkse = 0;
            int fphnum = 0;
            int sumFpzs = 0;
            boolean istrue = true;
            String pfqqlsh = UUIDUitl.UUID32(false);
            String invoiceInfoId = UUIDUitl.UUID32(false);
            List invoicDetail = new ArrayList();
            List ivoiceRelation = new ArrayList();
            //遍历明细
            for (int k = 0; k < details.size(); k++) {
                DocumentInfoDetailEntity info = details.get(k);
                double taxrate = Double.parseDouble(StringUtil.validator(info.getTaxRate(), "0")); // 税率
                double price = Double.parseDouble(StringUtil.validator(info.getUnitPriceOutTax(), "1")); // 单价
                double cost = Double.parseDouble(StringUtil.validator(info.getAmountWithoutTax(), "0"));// 未税金额
                double sum = Double.parseDouble(StringUtil.validator(info.getAmountWithTax(), "0"));// 含税金额
                double vat = Double.parseDouble(StringUtil.validator(info.getAmountWithoutTax(), "0"));// 未税金额
                String infoid = StringUtil.validator(info.getUuid());// 主键id
                String orderid = StringUtil.validator(info.getDocId());// 订单id
                String goodsname = StringUtil.validator(info.getPaymentName());// 订单id

                GoodsManageEntity goodsManageEntity = goodsManageService.getOne(new QueryWrapper<GoodsManageEntity>().eq("goods_name", goodsname));
                String yhzcbs = StringUtil.validator(goodsManageEntity.getPreferentialMark());// 优惠政策
                String lslbs = StringUtil.validator(info.getTaxRateFlag());// 零裞率标识
                String zzstsgl = StringUtil.validator(goodsManageEntity.getPreferentialName());//优惠政策名称
                String ssfldm = StringUtil.validator(goodsManageEntity.getTaxCode());//税收分类编码

                String dw = StringUtil.validator(goodsManageEntity.getUnit());//计量单位
                String ggxh = StringUtil.validator(goodsManageEntity.getModel());//规格型号

                double hsjeseold = sum;
                double seold = vat;
                double wsjeold = cost;

                double discountSum = Double.parseDouble(StringUtil.validator(info.getAmountWithoutTax(), "0"));// 折扣含税金额
                double discountCost = Double.parseDouble(StringUtil.validator(info.getAmountWithTax(), "0"));// 折扣金额
                double discountVat = Double.parseDouble(StringUtil.validator(info.getTaxAmount(), "0"));// 折扣税额
                double spsl = Double.parseDouble(StringUtil.validator(info.getQuantity(), "1"));// 商品数量
                price = Arith.div(cost, spsl);
                price = Arith.round(price, 8);

                if (baseSumTax.equals("0")) { // 含税
                    sum = Arith.round(sum, 2);
                    cost = Arith.round(Arith.mul(Arith.div(sum, (1 + taxrate)), 1), 2);
                    vat = Arith.sub(sum, cost);
                    if (cost == 0) {
                        vat = 0;
                    }

                    discountSum = Arith.round(discountSum, 2);
                    discountCost = Arith.round(Arith.mul(Arith.div(discountSum, (1 + taxrate)), 1), 2);
                    discountVat = Arith.sub(discountSum, discountCost);
                    if (discountCost == 0) {
                        discountVat = 0;
                        discountSum = 0;
                    }

                } else {// 未税
                    cost = Arith.round(cost, 2);
                    vat = Arith.round(Arith.mul(cost, taxrate), 2);
                    if (cost == 0) {
                        vat = 0;
                    }
                    sum = Arith.add(cost, vat);

                    discountCost = Arith.round(discountCost, 2);
                    discountVat = Arith.round(Arith.mul(discountCost, taxrate), 2);
                    if (discountCost == 0) {
                        discountVat = 0;
                    }
                    discountSum = Arith.add(discountCost, discountVat);

                }
                double kpxe = maxInvoiceMoeny;
                double kpxeStrp = maxInvoiceMoeny;
                boolean sfhbx = false;
                boolean sfghfp = false;

                if (k < details.size() - 1) {
                    DocumentInfoDetailEntity nextInfo = details.get(k + 1);
                    double nextSlv = Double.parseDouble(StringUtil.validator(nextInfo.getTaxRate(), "0")); // 税率
                    sfghfp = isSfghfp(sellerInvoiceRuleEntity, nextSlv, info);
                    sfhbx = isSfhbx(sellerInvoiceRuleEntity, nextInfo, info, sfghfp, goodsManageEntity, price, pmwsje, cost, nextSlv, taxrate);
                }

                //计算开票数量
                int numnn = 1;
                double stepZklv = Arith.div(discountSum, sum, 8);
                if (Arith.sub(sum, discountSum) > kpxe) {
                    double syKkpmje = Arith.sub(Arith.sub(sum, discountSum), Arith.sub(kpxe, pmhsje));
                    numnn = (int) Math.ceil(syKkpmje / kpxe) + 1;
                } else {
                    if (Arith.add(Arith.sub(sum, discountSum), pmhsje) > kpxe) {
                        numnn = 2;
                    }
                }
                double stmpWsjeSum = 0;
                double stmpHsjeSum = 0;
                double stmpSeSum = 0;
                double stmpZkjeSum = 0;
                double stmpZkSeSum = 0;
                double stmpZkHsjeSum = 0;
                double stmpSpslSum = 0;
                double cyhsje = 0;
                double cyse = 0;
                double cywsje = 0;
                int num = 0;
                //规格处理
                try {
                    num = ggxh.getBytes("GBK").length;
                    if (num > 36) {
                        String subAfter = ggxh.substring(0, 36);
                        int temp = 36;
                        while (36 < subAfter.getBytes("GBK").length) {
                            subAfter = subAfter.substring(0, --temp);
                        }
                        ggxh = subAfter;
                    }
                } catch (Exception e) {
                    log.error("", e);
                }

                //以开票数量为维度进行遍历 numnn：开票数量
                for (int x = 0; x < numnn; x++) {
                    double stepWsje = 0;
                    double stepHsje = 0;
                    double stepSe = 0;
                    double stepZkje = 0;
                    double stepZkhsje = 0;
                    double stepZkse = 0;
                    double stepSpsl = 0;
                    double stepBqpmje = Arith.sub(kpxe, pmhsje);
                    if (numnn == 1) {
                        stepZkje = discountCost;
                        stepWsje = cost;
                        stepSe = vat;
                        stepHsje = sum;
                        stepZkse = discountVat;
                        stepZkhsje = discountSum;
                        stepSpsl = spsl;
                        cyhsje = Arith.sub(hsjeseold, stepHsje);
                        cyse = Arith.sub(seold, stepSe);
                        cywsje = Arith.sub(wsjeold, stepWsje);
                    } else {
                        //商品数量大于1 金额小于限额
                        if (spsl > 1 && price < kpxe) {
                            if (x == 0) {
                                double zkJss = Arith.mul(stepBqpmje, stepZklv);
                                stepZkhsje = Arith.round(zkJss, 2);
                                double steWsl = Arith.round(Arith.div(Arith.add(stepBqpmje, zkJss), (1 + taxrate)), 2);
                                double stepsl = Math.floor(Arith.div(steWsl, price));
                                if (steWsl < price) {
                                    stepsl = 0;
                                }
                                stepBqpmje = Arith.mul(Arith.mul(stepsl, price), 1 + taxrate);
                                zkJss = Arith.mul(stepBqpmje, stepZklv);
                                //										stepBqpmje=Arith.round(stepBqpmje, 2);
                                stepBqpmje = Arith.round(Arith.sub(stepBqpmje, zkJss), 2);
                                kpxe = Arith.add(pmhsje, stepBqpmje);
                                zkJss = Arith.mul(kpxeStrp, stepZklv);
                                double steopnJs = Math.floor(Arith.div(Arith.div(Arith.add(kpxeStrp, zkJss), (1 + taxrate)), price));
                                int cNum = (int) Math.ceil(Arith.div(Arith.sub(spsl, stepsl), steopnJs));
                                numnn = cNum + 1;
                            } else if (x == 1) {
                                double zkJss = Arith.mul(kpxeStrp, stepZklv);
                                double steopnJs = Math.floor(Arith.div(Arith.div(Arith.add(kpxeStrp, zkJss), (1 + taxrate)), price));
                                double steWsl = Arith.round(Arith.mul(steopnJs, price), 2);
                                kpxe = Arith.mul(steWsl, 1 + taxrate);
                                zkJss = Arith.mul(kpxe, stepZklv);
                                kpxe = Arith.round(Arith.sub(kpxe, zkJss), 2);
                            }
                            stepBqpmje = Arith.sub(kpxe, pmhsje);
                            stepBqpmje = Arith.round(stepBqpmje, 2);
                        }
                        if (x < numnn - 1) {
                            stepZkhsje = Arith.mul(Arith.div(stepBqpmje, (1 - stepZklv)), stepZklv);
                            stepZkhsje = Arith.round(stepZkhsje, 2);
                            stepZkje = Arith.round(Arith.div(stepZkhsje, (1 + taxrate)), 2);
                            stepZkse = Arith.sub(stepZkhsje, stepZkje);
                            stepHsje = Arith.add(stepBqpmje, stepZkhsje);
                            stepWsje = Arith.round(Arith.div(stepHsje, (1 + taxrate)), 2);
                            stepSe = Arith.sub(stepHsje, stepWsje);

                            stmpWsjeSum = Arith.add(stmpWsjeSum, stepWsje);
                            stmpHsjeSum = Arith.add(stmpHsjeSum, stepHsje);
                            stmpZkjeSum = Arith.add(stmpZkjeSum, stepZkje);
                            stmpSeSum = Arith.add(stmpSeSum, stepSe);
                            stmpZkHsjeSum = Arith.add(stmpZkHsjeSum, stepZkhsje);
                            stepSpsl = Arith.round(Arith.div(stepWsje, price), 2);
                            stmpSpslSum = Arith.add(stmpSpslSum, stepSpsl);
                        } else {
                            kpxe = kpxeStrp;
                            if (baseSumTax.equals("0")) {
                                stepHsje = Arith.sub(sum, stmpHsjeSum);
                                stepWsje = Arith.round(Arith.mul(Arith.div(stepHsje, (1 + taxrate)), 1), 2);
                                stepSe = Arith.sub(stepHsje, stepWsje);
                                stepZkhsje = Arith.sub(discountSum, stmpZkHsjeSum);
                                stepZkje = Arith.round(Arith.mul(Arith.div(stepZkhsje, (1 + taxrate)), 1), 2);
                                stepZkse = Arith.sub(stepZkhsje, stepZkje);
                            } else {
                                stepWsje = Arith.sub(cost, stmpWsjeSum);
                                stepSe = Arith.round(Arith.mul(stepWsje, taxrate), 2);
                                stepHsje = Arith.add(stepWsje, stepSe);
                                stepZkje = Arith.sub(discountCost, stmpZkjeSum);
                                stepZkse = Arith.round(Arith.mul(stepZkje, taxrate), 2);
                                stepZkhsje = Arith.add(stepZkje, stepZkse);
                            }
                            cyhsje = Arith.sub(hsjeseold, stepHsje);
                            cyse = Arith.sub(seold, stepSe);
                            cywsje = Arith.sub(wsjeold, stepWsje);
                            stepSpsl = Arith.sub(spsl, stmpSpslSum);
                        }
                    }
                    int fphxz = 0;
                    // 合并
                    wsjeSum = Arith.add(wsjeSum, stepWsje);
                    seSum = Arith.add(seSum, stepSe);
                    hsjeSum = Arith.add(hsjeSum, stepHsje);
                    zkwsjeSum = Arith.add(zkwsjeSum, stepZkje);
                    zkseSum = Arith.add(zkseSum, stepZkse);
                    zkhsjeSum = Arith.add(zkhsjeSum, stepZkhsje);
                    spslSum = Arith.add(spslSum, stepSpsl);
                    double stepWsjeSum = wsjeSum;
                    double stepseSum = seSum;
                    double stephsjeSum = hsjeSum;
                    double stepzkwsjeSum = zkwsjeSum;
                    double stepzkseSum = zkseSum;
                    double stepzkhsjeSum = zkhsjeSum;
                    if (baseSumTax.equals("0")) { // 含税
                        hsjeSum = Arith.round(hsjeSum, 2);
                        wsjeSum = Arith.round(Arith.mul(Arith.div(hsjeSum, (1 + taxrate)), 1), 2);
                        seSum = Arith.sub(hsjeSum, wsjeSum);
                        zkhsjeSum = Arith.round(zkhsjeSum, 2);
                        zkwsjeSum = Arith.round(Arith.mul(Arith.div(zkhsjeSum, (1 + taxrate)), 1), 2);
                        zkseSum = Arith.sub(zkhsjeSum, zkwsjeSum);
                        if (wsjeSum == 0) {
                            seSum = 0;
                            zkseSum = 0;
                            zkwsjeSum = 0;
                            hsjeSum = 0;
                            zkhsjeSum = 0;
                        }
                    } else {// 未税
                        wsjeSum = Arith.round(wsjeSum, 2);
                        seSum = Arith.round(Arith.mul(wsjeSum, taxrate), 2);
                        zkwsjeSum = Arith.round(zkwsjeSum, 2);
                        zkseSum = Arith.round(Arith.mul(zkwsjeSum, taxrate), 2);
                        if (wsjeSum == 0) {
                            seSum = 0;
                            zkseSum = 0;
                            zkwsjeSum = 0;
                        }
                        hsjeSum = Arith.add(wsjeSum, seSum);
                        zkhsjeSum = Arith.add(zkwsjeSum, zkseSum);
                    }
                    stepWsje = Arith.sub(stepWsje, Arith.sub(stepWsjeSum, wsjeSum));
                    stepHsje = Arith.sub(stepHsje, Arith.sub(stephsjeSum, hsjeSum));
                    stepSe = Arith.sub(stepSe, Arith.sub(stepseSum, seSum));
                    stepZkje = Arith.sub(stepZkje, Arith.sub(stepzkwsjeSum, zkwsjeSum));
                    stepZkhsje = Arith.sub(stepZkhsje, Arith.sub(stepzkhsjeSum, zkhsjeSum));
                    stepZkse = Arith.sub(stepZkse, Arith.sub(stepzkseSum, zkseSum));
                    pmwsje = Arith.add(pmwsje, Arith.sub(stepWsje, stepZkje));
                    pmhsje = Arith.add(pmhsje, Arith.sub(stepHsje, stepZkhsje));
                    pmse = Arith.add(pmse, Arith.sub(stepSe, stepZkse));
                    pmzkwsje = Arith.add(pmzkwsje, stepZkje);
                    pmzkhsje = Arith.add(pmzkhsje, stepZkhsje);
                    pmzkse = Arith.add(pmzkse, stepZkse);
                    if (spslSum == 0) {
                        spslSum = 1;
                    }
                    if (sfghfp) {
                        if (!sfhbx) {
                            if (wsjeSum > 0 || (isZF.equals("fs") && wsjeSum != 0)) {
                                if (zkwsjeSum > 0) {
                                    fphxz = 2;
                                }
                                fphnum++;
                                invoicDetail = addInvoicDetail(invoicDetail, invoiceInfoId, pfqqlsh, fphnum, fphxz, goodsname,
                                        baseUintNum, spslSum, price, ggxh, dw, wsjeSum, taxrate, seSum, hsjeSum, ssfldm, yhzcbs,
                                        lslbs, zzstsgl, zkwsjeSum, zkseSum, zkhsjeSum);
                                ivoiceRelation = addIvoiceRelation(ivoiceRelation, orderid, infoid, invoiceInfoId, pfqqlsh, checkRecordNo);
                                if (fphxz == 2) {
                                    fphnum++;
                                    invoicDetail = addInvoicDetailCondition(invoicDetail, pfqqlsh, fphnum, goodsname, zkwsjeSum, zkhsjeSum,
                                            taxrate, zkseSum, ssfldm, yhzcbs, lslbs, zzstsgl);
                                }
                            }
                            wsjeSum = 0;
                            seSum = 0;
                            hsjeSum = 0;
                            zkwsjeSum = 0;
                            zkseSum = 0;
                            zkhsjeSum = 0;
                            spslSum = 0;
                            if (Arith.sub(kpxe, pmhsje) == 0 || (fphnum == maxRowNumber)) {
                                invoiceList = addInvoiceList(sellerInvoiceRuleEntity, invoiceList, pmse, pmwsje, pmhsje, pfqqlsh,
                                        baseSumTax, taxrate, invoiceType, sellerTaxno, sellerName, sellerAddrTel, sellerBank, buyerTaxno,
                                        buyerName, buyerAddrTel, buyerBank, remark, checkRecordNo, pmzkhsje,
                                        pmzkse, pmzkwsje, sellerOrderEntity, invoicDetail, ivoiceRelation);
                                pmwsje = 0;
                                pmhsje = 0;
                                pmse = 0;
                                pmzkwsje = 0;
                                pmzkhsje = 0;
                                pmzkse = 0;
                                fphnum = 0;
                                pfqqlsh = UUIDUitl.UUID32(false);
                                ivoiceRelation = new ArrayList();
                                invoicDetail = new ArrayList();
                                sumFpzs++;
                            }
                            invoiceInfoId = UUIDUitl.UUID32(false);
                        } else {
                            ivoiceRelation = addIvoiceRelation(ivoiceRelation, orderid, infoid, invoiceInfoId, pfqqlsh, checkRecordNo);
                            if (Arith.sub(kpxe, pmhsje) == 0 || (fphnum == maxRowNumber)) {
                                if (wsjeSum > 0 || (isZF.equals("fs") && wsjeSum != 0)) {
                                    if (zkwsjeSum > 0) {
                                        fphxz = 2; // 被折扣行
                                    }
                                    fphnum++;
                                    invoicDetail = addInvoicDetail(invoicDetail, invoiceInfoId, pfqqlsh, fphnum, fphxz, goodsname,
                                            baseUintNum, spslSum, price, ggxh, dw, wsjeSum, taxrate, seSum, hsjeSum, ssfldm, yhzcbs,
                                            lslbs, zzstsgl, zkwsjeSum, zkseSum, zkhsjeSum);
                                    if (fphxz == 2) {
                                        fphnum++;
                                        invoicDetail = addInvoicDetailCondition(invoicDetail, pfqqlsh, fphnum, goodsname, zkwsjeSum, zkhsjeSum,
                                                taxrate, zkseSum, ssfldm, yhzcbs, lslbs, zzstsgl);
                                    }
                                }
                                invoiceList = addInvoiceList(sellerInvoiceRuleEntity, invoiceList, pmse, pmwsje, pmhsje, pfqqlsh,
                                        baseSumTax, taxrate, invoiceType, sellerTaxno, sellerName, sellerAddrTel, sellerBank, buyerTaxno,
                                        buyerName, buyerAddrTel, buyerBank, remark, checkRecordNo, pmzkhsje,
                                        pmzkse, pmzkwsje, sellerOrderEntity, invoicDetail, ivoiceRelation);
                                wsjeSum = 0;
                                seSum = 0;
                                hsjeSum = 0;
                                zkwsjeSum = 0;
                                zkseSum = 0;
                                zkhsjeSum = 0;
                                spslSum = 0;
                                pmwsje = 0;
                                pmhsje = 0;
                                pmse = 0;
                                pmzkwsje = 0;
                                pmzkhsje = 0;
                                pmzkse = 0;
                                fphnum = 0;
                                ivoiceRelation = new ArrayList();
                                invoiceInfoId = UUIDUitl.UUID32(false);
                                invoicDetail = new ArrayList();
                                pfqqlsh = UUIDUitl.UUID32(false);
                                sumFpzs++;
                            }
                        }
                    } else {
                        if (Math.abs(wsjeSum) > 0) {
                            if (zkwsjeSum > 0) {
                                fphxz = 2; // 被折扣行
                            }
                            fphnum++;
                            invoicDetail = addInvoicDetail(invoicDetail, invoiceInfoId, pfqqlsh, fphnum, fphxz, goodsname,
                                    baseUintNum, spslSum, price, ggxh, dw, wsjeSum, taxrate, seSum, hsjeSum, ssfldm, yhzcbs,
                                    lslbs, zzstsgl, zkwsjeSum, zkseSum, zkhsjeSum);
                            ivoiceRelation = addIvoiceRelation(ivoiceRelation, orderid, infoid, invoiceInfoId, pfqqlsh, checkRecordNo);
                            if (fphxz == 2) {
                                fphnum++;
                                invoicDetail = addInvoicDetailCondition(invoicDetail, pfqqlsh, fphnum, goodsname, zkwsjeSum, zkhsjeSum,
                                        taxrate, zkseSum, ssfldm, yhzcbs, lslbs, zzstsgl);
                            }
                        }
                        invoiceList = addInvoiceList(sellerInvoiceRuleEntity, invoiceList, pmse, pmwsje, pmhsje, pfqqlsh,
                                baseSumTax, taxrate, invoiceType, sellerTaxno, sellerName, sellerAddrTel, sellerBank, buyerTaxno,
                                buyerName, buyerAddrTel, buyerBank, remark, checkRecordNo, pmzkhsje,
                                pmzkse, pmzkwsje, sellerOrderEntity, invoicDetail, ivoiceRelation);
                        wsjeSum = 0;
                        seSum = 0;
                        hsjeSum = 0;
                        zkwsjeSum = 0;
                        zkseSum = 0;
                        zkhsjeSum = 0;
                        spslSum = 0;
                        pmwsje = 0;
                        pmhsje = 0;
                        pmse = 0;
                        pmzkwsje = 0;
                        pmzkhsje = 0;
                        pmzkse = 0;
                        fphnum = 0;
                        ivoiceRelation = new ArrayList();
                        invoiceInfoId = UUIDUitl.UUID32(false);
                        invoicDetail = new ArrayList();
                        pfqqlsh = UUIDUitl.UUID32(false);
                        sumFpzs++;
                    }
                }
                if (k == details.size() && pmwsje != 0) {
                    invoiceList = addInvoiceList(sellerInvoiceRuleEntity, invoiceList, pmse, pmwsje, pmhsje, pfqqlsh,
                            baseSumTax, taxrate, invoiceType, sellerTaxno, sellerName, sellerAddrTel, sellerBank, buyerTaxno,
                            buyerName, buyerAddrTel, buyerBank, remark, checkRecordNo, pmzkhsje,
                            pmzkse, pmzkwsje, sellerOrderEntity, invoicDetail, ivoiceRelation);
                    wsjeSum = 0;
                    seSum = 0;
                    hsjeSum = 0;
                    zkwsjeSum = 0;
                    zkseSum = 0;
                    zkhsjeSum = 0;
                    spslSum = 0;
                    fphnum = 0;
                    pmwsje = 0;
                    pmhsje = 0;
                    pmse = 0;
                    pmzkwsje = 0;
                    pmzkhsje = 0;
                    pmzkse = 0;
                    ivoiceRelation = new ArrayList();
                    invoiceInfoId = UUIDUitl.UUID32(false);
                    invoicDetail = new ArrayList();
                    pfqqlsh = UUIDUitl.UUID32(false);
                    sumFpzs++;
                }
            }
        }
        return invoiceList;
    }

    /**
     * @return boolean
     */
    private boolean isSfhbx(SellerInvoiceRuleEntity sellerInvoiceRuleEntity, DocumentInfoDetailEntity nextInfo, DocumentInfoDetailEntity info,
                            boolean sfghfp, GoodsManageEntity goodsManageEntity, double price, double pmwsje, double cost, double nextSlv, double taxrate) {
        String mergeGoodName = sellerInvoiceRuleEntity.getMergeGoodName();
        String goodsname = StringUtil.validator(info.getPaymentName());// 订单id
        double nextPrice = Double.parseDouble(StringUtil.validator(nextInfo.getUnitPriceOutTax(), "1")); // 单价
        String nextSpmc = StringUtil.validator(nextInfo.getPaymentName());// 订单id
        String nextDw = StringUtil.validator(nextInfo.getQuantityUnit());//
        String nextGgxh = StringUtil.validator(nextInfo.getItemSpec());
        String mergeGoodType = sellerInvoiceRuleEntity.getMergeGoodType();
        String mergeUnit = sellerInvoiceRuleEntity.getMergeUnit();
        String mergeUnitPrice = sellerInvoiceRuleEntity.getMergeUnitPrice();
        String ggxh = StringUtil.validator(goodsManageEntity.getModel());
        String dw = StringUtil.validator(goodsManageEntity.getUnit());//
        boolean sfhbx = true;
        if (goodsname.equals(nextSpmc) && mergeGoodName.equals("1") && sfghfp) {
            if (mergeGoodType.equals("1")) {
                if (ggxh.equals(nextGgxh)) {
                    sfhbx = true;
                } else {
                    sfhbx = false;
                }
            }
            if (mergeUnit.equals("1")) {
                if (dw.equals(nextDw)) {
                    sfhbx = true;
                } else {
                    sfhbx = false;
                }
            }
            if (mergeUnitPrice.equals("1")) {
                if (price == nextPrice) {
                    sfhbx = true;
                } else {
                    sfhbx = false;
                }
            }
            if (Arith.add(pmwsje, cost) < 0) {
                sfhbx = true;
            }
            if (nextSlv == taxrate && sfhbx) {
                sfhbx = true;
            } else {
                sfhbx = false;
            }
        }
        return sfhbx;
    }

    /**
     * @return boolean
     */
    private boolean isSfghfp(SellerInvoiceRuleEntity sellerInvoiceRuleEntity, double nextSlv, DocumentInfoDetailEntity info) {
        String mergeTaxRate = sellerInvoiceRuleEntity.getMergeTaxRate();
        double taxrate = Double.parseDouble(StringUtil.validator(info.getTaxRate(), "0")); // 税率
        boolean sfghfp = false;
        if ("1".equals(mergeTaxRate)) {
            if (nextSlv == taxrate) {
                sfghfp = true;
            } else {
                sfghfp = false;
            }
        } else {
            sfghfp = true;
        }
        return sfghfp;
    }

    /**
     * @param ivoiceRelation
     * @return
     */
    private List addInvoiceList(SellerInvoiceRuleEntity sellerInvoiceRuleEntity, List invoiceList, double pmse, double pmwsje, double pmhsje, String pfqqlsh,
                                String baseSumTax, double taxrate, String invoiceType, String sellerTaxno, String sellerName, String sellerAddrTel, String sellerBank,
                                String buyerTaxno, String buyerName, String buyerAddrTel, String buyerBank, String remark, String checkRecordNo, double pmzkhsje,
                                double pmzkse, double pmzkwsje, DocumentInfoEntity sellerOrderEntity, List invoicDetail, List ivoiceRelation) {

        String baseUintNum = sellerInvoiceRuleEntity.getBaseUintNum();//拆分规则:单价数量 等于1是以数量 其它则是单价
        String reviewer = sellerInvoiceRuleEntity.getReviewer();//复核人
        String payee = sellerInvoiceRuleEntity.getPayee();//收款人
        String drawer = sellerInvoiceRuleEntity.getDrawer();//开票人

        double stepmwsje = Arith.round(Arith.div(pmhsje, 1 + taxrate), 2);
        double stepmse = Arith.sub(pmhsje, stepmwsje);
        Map mapInvoice = new HashMap();
        mapInvoice.put("ceFlag", "0");
        if (Math.abs(Arith.sub(stepmse, pmse)) > 0) {
            mapInvoice.put("ceFlag", "1");
            Map<String, Comparable> ycfpmap = new HashMap<String, Comparable>();
            ycfpmap.put("pmwsje", pmwsje);
            ycfpmap.put("stepmwsje", stepmwsje);
            ycfpmap.put("pmhsje", pmhsje);
            ycfpmap.put("pmse", pmse);
            ycfpmap.put("stepmse", stepmse);
            ycfpmap.put("pfqqlsh", pfqqlsh);
            ycfpmap.put("isPrice", baseUintNum);
            ycfpmap.put("isInvoiceSum", baseSumTax);
            ycfpmap.put("taxrate", taxrate);
            mapInvoice.put("ycfpmap", ycfpmap);
        }
        mapInvoice.put("id", UUIDUitl.UUID32(false));
        mapInvoice.put("pfqqlsh", pfqqlsh);
        mapInvoice.put("fplxdm", invoiceType);
        mapInvoice.put("kplx", 0);
        mapInvoice.put("xfsh", sellerTaxno);
        mapInvoice.put("xfmc", sellerName);
        mapInvoice.put("xfdzdh", sellerAddrTel);
        mapInvoice.put("xfyhzh", sellerBank);
        mapInvoice.put("gfsh", buyerTaxno);
        mapInvoice.put("gfmc", buyerName);
        mapInvoice.put("gfdzdh", buyerAddrTel);
        mapInvoice.put("gfyhzh", buyerBank);
        mapInvoice.put("hjje", pmwsje);
        mapInvoice.put("hjse", pmse);
        mapInvoice.put("jshj", pmhsje);
        mapInvoice.put("fhr", reviewer);
        mapInvoice.put("skr", payee);
        mapInvoice.put("kpr", drawer);
        mapInvoice.put("bz", remark);
        mapInvoice.put("gdjlh", checkRecordNo);
        mapInvoice.put("zkjshj", pmzkhsje);
        mapInvoice.put("zkse", pmzkse);
        mapInvoice.put("zkje", pmzkwsje);
        mapInvoice.put("slv", taxrate);
        mapInvoice.put("gfgsbm", "");
        mapInvoice.put("xfgsbm", "");
        mapInvoice.put("ddbh", sellerOrderEntity.getDocId());
        mapInvoice.put("invoiceInfo", invoicDetail);
        mapInvoice.put("ivoiceRelation", ivoiceRelation);
        invoiceList.add(mapInvoice);
        return invoiceList;
    }

    /**
     * @param invoicDetail
     * @return
     */
    private List addInvoicDetailCondition(List invoicDetail, String pfqqlsh, double fphnum, String goodsname, double zkwsjeSum, double zkhsjeSum,
                                          double taxrate, double zkseSum, String ssfldm, String yhzcbs, String lslbs, String zzstsgl) {
        Map mapInfoZK = new HashMap();
        mapInfoZK.put("id", UUIDUitl.UUID32(false));
        mapInfoZK.put("pfqqlsh", pfqqlsh);
        mapInfoZK.put("mxxh", fphnum);
        mapInfoZK.put("fphxz", "1");
        mapInfoZK.put("spmc", goodsname);
        mapInfoZK.put("je", -1 * zkwsjeSum);
        mapInfoZK.put("slv", taxrate);
        mapInfoZK.put("se", -1 * zkseSum);
        mapInfoZK.put("hjje", -1 * zkhsjeSum);
        mapInfoZK.put("hsbz", "0");
        mapInfoZK.put("ssfldm", ssfldm);
        mapInfoZK.put("yhzcbs", yhzcbs);
        mapInfoZK.put("lslbs", lslbs);
        mapInfoZK.put("zzstsgl", zzstsgl);
        invoicDetail.add(mapInfoZK);
        return invoicDetail;
    }


    /**
     * @param invoicDetail
     * @return
     */
    private List addInvoicDetail(List invoicDetail, String invoiceInfoId, String pfqqlsh, double fphnum, double fphxz, String goodsname,
                                 String baseUintNum, double spslSum, double price, String ggxh, String dw, double wsjeSum, double taxrate, double seSum, double hsjeSum,
                                 String ssfldm, String yhzcbs, String lslbs, String zzstsgl, double zkwsjeSum, double zkseSum, double zkhsjeSum) {
        double mxhSpsl = 1; // 明细行数量
        double mxhDj = 1; // 明细行单价
        if (baseUintNum.equals("1")) {
            // 以 数量为基准
            mxhSpsl = Math.abs(spslSum);
            mxhDj = Arith.div(wsjeSum, mxhSpsl, 8);
        } else {
            // 以单价为基准
            mxhDj = price;
            mxhSpsl = Arith.div(wsjeSum, mxhDj, 8);
        }
        Map mapInfo = new HashMap();
        mapInfo.put("id", invoiceInfoId);
        mapInfo.put("pfqqlsh", pfqqlsh);
        mapInfo.put("mxxh", fphnum);
        mapInfo.put("fphxz", fphxz);
        mapInfo.put("spmc", goodsname);
        mapInfo.put("ggxh", ggxh);
        mapInfo.put("dw", dw);
        mapInfo.put("sl", mxhSpsl);
        mapInfo.put("dj", mxhDj);
        mapInfo.put("je", wsjeSum);
        mapInfo.put("slv", taxrate);
        mapInfo.put("se", seSum);
        mapInfo.put("hjje", hsjeSum);
        mapInfo.put("hsbz", "0");
        mapInfo.put("ssfldm", ssfldm);
        mapInfo.put("yhzcbs", yhzcbs);
        mapInfo.put("lslbs", lslbs);
        mapInfo.put("zzstsgl", zzstsgl);
        mapInfo.put("zkje", -1 * zkwsjeSum);
        mapInfo.put("zkse", -1 * zkseSum);
        mapInfo.put("zkhsje", -1 * zkhsjeSum);
        invoicDetail.add(mapInfo);
        return invoicDetail;
    }

    /**
     * @param ivoiceRelation
     * @return
     */
    private List addIvoiceRelation(List ivoiceRelation, String orderid, String infoid, String invoiceInfoId, String pfqqlsh, String checkRecordNo) {
        Map ivoiceRelationMap = new HashMap();
        ivoiceRelationMap.put("orderid", orderid);
        ivoiceRelationMap.put("infoid", infoid);
        ivoiceRelationMap.put("fpinfoid", invoiceInfoId);
        ivoiceRelationMap.put("fpqqlsh", pfqqlsh);
        ivoiceRelationMap.put("gdjlh", checkRecordNo);
        ivoiceRelation.add(ivoiceRelationMap);
        return ivoiceRelation;
    }


    private static List createOrdList(String flag, String isgoodsName, String isgoodsSpecification, String isgoodsUnit, String isgoodsPrice, List<DocumentInfoDetailEntity> details) {
        System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
        details = details.stream().sorted(Comparator.comparing(DocumentInfoDetailEntity::getTaxRate).thenComparing(DocumentInfoDetailEntity::getPaymentName)).collect(Collectors.toList());

        List<Map> ltOrder = new ArrayList();
        if (isgoodsName.equals("1")) {
            List<Map> lt = new ArrayList();
            String name = "";
            String rate = "";

            BigDecimal sum = BigDecimal.valueOf(0);
            for (int i = 0; i < details.size(); i++) {
                DocumentInfoDetailEntity maps = (DocumentInfoDetailEntity) details.get(i);
                String step = maps.getTaxRate() + maps.getPaymentName();

                if (isgoodsSpecification.equals("1")) {
                    step = step + maps.getPaymentType();
                }
                if (isgoodsUnit.equals("1")) {
                    step = step + maps.getQuantityUnit();
                }
                if (isgoodsPrice.equals("1")) {
                    step = step + maps.getUnitPriceOutTax();
                }

                try {
                    if (i == 0) {
                        name = step;
                        rate = maps.getTaxRate().toString();
                        sum = NumberUtil.round(maps.getAmountWithoutTax(), 2);
                    } else {
                        if (name.equals(step)) {
                            sum = NumberUtil.add(sum, NumberUtil.round(maps.getAmountWithoutTax(), 2));
                            rate = maps.getTaxRate().toString();
                        } else {
                            Map mapStep = new HashMap();
                            mapStep.put("name", name);
                            mapStep.put("sum", sum);
                            mapStep.put("rate", rate);
                            lt.add(mapStep);
                            name = step;
                            rate = maps.getTaxRate().toString();
                            sum = NumberUtil.round(maps.getAmountWithoutTax(), 2);
                        }

                    }
                    if (i == details.size() - 1) {
                        Map mapStep = new HashMap();
                        mapStep.put("name", name);
                        mapStep.put("sum", sum);
                        mapStep.put("rate", rate);
                        lt.add(mapStep);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }


            Comparator<DocumentInfoDetailEntity> comparator = (h1, h2) -> NumberUtil.round(h1.getAmountWithoutTax(), 2).compareTo(NumberUtil.round(h2.getAmountWithoutTax(), 2));
            details.sort(comparator);
            List<DocumentInfoDetailEntity> infolistForZs = new ArrayList();
            List<DocumentInfoDetailEntity> infolistForFs = new ArrayList();
            for (int j = 0; j < lt.size(); j++) {
                Map mapas = (Map) lt.get(j);
                String stepO = mapas.get("name").toString();
                String sumO = mapas.get("sum").toString();
                for (Iterator iterator = details.iterator(); iterator.hasNext(); ) {
                    DocumentInfoDetailEntity maps = (DocumentInfoDetailEntity) iterator.next();
                    String stepT = maps.getTaxRate() + maps.getPaymentName();
                    if (isgoodsSpecification.equals("1")) {
                        stepT = stepT + maps.getItemSpec();
                    }
                    if (isgoodsUnit.equals("1")) {
                        stepT = stepT + maps.getQuantityUnit();
                    }
                    if (isgoodsPrice.equals("1")) {
                        stepT = stepT + maps.getUnitPriceOutTax();
                    }
                    if (NumberUtil.round(sumO, 2).doubleValue() > 0) {
//                        maps.setIsTrue("0");
                    } else {
//                        maps.setIsTrue("1");
                    }
                    if (stepO.equals(stepT)) {
                        if (flag.equals("0")) {
                            if (NumberUtil.round(sumO, 2).doubleValue() > 0) {
                                infolistForZs.add(maps);
                            } else {
                                infolistForFs.add(maps);
                            }
                        } else {
                            infolistForFs.add(maps);
                        }

                        iterator.remove();
                    }
                }
            }
            if (infolistForZs.size() > 0) {
                Map mapZs = new HashMap();
                mapZs.put("data", infolistForZs);
                mapZs.put("flag", "zs");
                ltOrder.add(mapZs);
            }
            if (infolistForFs.size() > 0) {
                Map mapFs = new HashMap();
                mapFs.put("data", infolistForFs);
                mapFs.put("flag", "fs");
                ltOrder.add(mapFs);
            }
            return ltOrder;
        } else {
            Map mapZs = new HashMap();
            mapZs.put("data", details);
            mapZs.put("flag", "zs");
            ltOrder.add(mapZs);
            return ltOrder;
        }

    }

    public void insertIntoInvoiceTable(List list) {
        String aa = "";
        if (org.springframework.util.CollectionUtils.isEmpty(list)) {
            throw new RuntimeException("数据加工异常");
        } else {
            for (Object m : list) {
                List<Map<String, Object>> relationsList = new ArrayList<>();
                List<SellerInvoiceDetailEntity> invoiceDetailList = new ArrayList<>();
                Map<String, Object> map = (Map<String, Object>) m;
                SellerInvoiceEntity invoice = new SellerInvoiceEntity();
                //invoice.setInvoiceState("0");
                invoice.setPurchaserName(StringUtil.validator(map.get("gfmc")));
                invoice.setPurchaserCode(StringUtil.validator(map.get("gfbm")));
                invoice.setPurchaserTaxNo(StringUtil.validator(map.get("gfsh")));
                invoice.setPurchaserBankAccount(StringUtil.validator(map.get("gfyhzh")));
                invoice.setTotalSum(StringUtil.validator(map.get("hjje")));
                invoice.setDiscountSum(StringUtil.validator(map.get("zkje")));
                invoice.setRemark(StringUtil.validator(map.get("bz")));
                invoice.setSellerAddressTel(StringUtil.validator(map.get("xfdzdh")));
                invoice.setUuid(StringUtil.validator(map.get("id")));
                invoice.setPayee(StringUtil.validator(map.get("skr")));
                String fpqqlsh = StringUtil.validator(map.get("pfqqlsh"));
                invoice.setSerialNo(fpqqlsh);
                invoice.setTotalTax(StringUtil.validator(map.get("hjse")));
                invoice.setDrawer(StringUtil.validator(map.get("kpr")));
                invoice.setSellerBankAccount(StringUtil.validator(map.get("xfyhzh")));
                invoice.setReviewer(StringUtil.validator(map.get("fhr")));
                String gdjlh = StringUtil.validator(map.get("gdjlh"));
//                invoice.setInvoiceRecord(gdjlh);
                String fplxdm = StringUtil.validator(map.get("fplxdm"));
                invoice.setInvoiceType(fplxdm);
                invoice.setPurchaserAddressTel(StringUtil.validator(map.get("gfdzdh")));
                invoice.setDiscountSumTax(StringUtil.validator(map.get("zkjshj")));
                invoice.setTotalSumTax(StringUtil.validator(map.get("jshj")));
                invoice.setDiscountTax(StringUtil.validator(map.get("zkse")));
                invoice.setSellerTaxNo(StringUtil.validator(map.get("xfsh")));
                invoice.setSellerName(StringUtil.validator(map.get("xfmc")));
                invoice.setSellerCode(StringUtil.validator(map.get("xfbm")));
                invoice.setTaxRate(StringUtil.validator(map.get("slv")));
                invoice.setOrderNo(StringUtil.validator(map.get("ddbh")));
                invoice.setPhone(StringUtil.validator(map.get("phone")));
                invoice.setDataSource(StringUtil.validator(map.get("dataSource")));
                invoice.setMakeInvoiceState("0");

                List relations = (List) map.get("ivoiceRelation");
                //负数专票入红字表
                double hjje = MapUtils.getDouble(map, "hjje", 0.0);
                List invoiceInfos = (List) map.get("invoiceInfo");

                if (hjje < 0) {
                    invoice.setMakeInvoiceType("1");
                } else {
                    invoice.setMakeInvoiceType("0");
                }

                int detailSize = invoiceInfos.size();
                // 入明细表
                for (int i = 0; i < detailSize; i++) {
                    Map<String, Object> vatDetail = (Map<String, Object>) invoiceInfos.get(i);

                    SellerInvoiceDetailEntity detail = new SellerInvoiceDetailEntity();
                    detail.setModel(StringUtil.validator(vatDetail.get("ggxh")));
                    detail.setGoodsName(StringUtil.validator(vatDetail.get("spmc")));
                    detail.setUnitPrice(StringUtil.validator(vatDetail.get("dj")));
                    detail.setDetailNo(StringUtil.validator(vatDetail.get("mxxh")));
                    detail.setTaxCode(StringUtil.validator(vatDetail.get("ssfldm")));
                    detail.setInvoiceRowNature(StringUtil.validator(vatDetail.get("fphxz")));
                    detail.setTaxRateMark(StringUtil.validator(vatDetail.get("lslbs")));

                    detail.setUnit(StringUtil.validator(vatDetail.get("dw")));
                    detail.setGoodsNumber(StringUtil.validator(vatDetail.get("sl")));
                    detail.setUuid(StringUtil.validator(vatDetail.get("id")));
                    detail.setGoodsSum(StringUtil.validator(vatDetail.get("je")));
                    detail.setGoodTax(StringUtil.validator(vatDetail.get("se")));
                    detail.setGoodsSumTax(StringUtil.validator(vatDetail.get("hjje")));
                    detail.setTaxRate(StringUtil.validator(vatDetail.get("slv")));
                    detail.setSerialNo(StringUtil.validator(vatDetail.get("pfqqlsh")));
                    detail.setPreferentialMark(StringUtil.validator(vatDetail.get("yhzcbs")));
                    detail.setPreferentialName(StringUtil.validator(vatDetail.get("zzstsgl")));
                    invoiceDetailList.add(detail);
                }

                invoicedService.save(invoice);
                invoiceDetailService.saveBatch(invoiceDetailList);
            }
        }
    }


    /**
     * 明源发票作废红冲
     *
     * @param cancelInvoiceDTO
     * @return
     */
    public Response invoiceCancel(CancelInvoiceDTO cancelInvoiceDTO) {
 /*       List<String> docIds = cancelInvoiceDTO.getDocId();
        for (String docId : docIds) {
            CancelDocDetailEntity cancelDocDetailEntity = new CancelDocDetailEntity();
            cancelDocDetailEntity.setUuid(UUIDUitl.UUID32(false));
            cancelDocDetailEntity.setDocId(docId);
            cancelDocDetailEntity.setCancelStatus(CodeConstant.DCL);
            cancelDocDetailMapper.insert(cancelDocDetailEntity);
        }
        //异步处理发票作废、红冲
        asyncDocumentService.dealCancelInvoice(docIds);*/
        return Response.success();
    }



    /**
     * 同步明源项目信息
     *
     * @return
     */
    /*public Response syncProject() {
        Response response = apiClientService.syncProjectInfo();
        String result = (String) response.getData();
        JSONObject projectInfo = JSON.parseObject(result);
        String resultCode = projectInfo.getString("rtn");
        String message = projectInfo.getString("message");
        if (CodeConstant.OK.equals(resultCode)) {
            JSONArray projectDetail = projectInfo.getJSONArray("projectData");
            int projectNumber = projectDetail.size();
            for (int i = 0; i < projectNumber; i++) {
                ProjectInfoEntity projectInfoEntity = new ProjectInfoEntity();
                JSONObject project = projectDetail.getJSONObject(i);
                String projectName = project.getString("ProjName");
                String projectCode = project.getString("ProjCode");
                String xffk = project.getString("XfFk");
                String xfjz = project.getString("XfJz");
                projectInfoEntity.setProjectName(projectName);
                projectInfoEntity.setProjectCode(projectCode);
                projectInfoEntity.setXfFK(xffk);
                projectInfoEntity.setXfJz(xfjz);
                projectInfoEntity.setEnableTag(CodeConstant.ENABLE);
                QueryWrapper<ProjectInfoEntity> projectQuery = new QueryWrapper<>();
                projectQuery.eq("project_name", projectName);
                projectQuery.eq("project_code", projectCode);
                if (projectInfoMapper.selectCount(projectQuery) > 0) {
                    projectInfoMapper.update(projectInfoEntity, projectQuery);
                } else {
                    projectInfoEntity.setUuid(UUIDUitl.UUID32(false));
                    projectInfoMapper.insert(projectInfoEntity);
                }
            }
        } else if (CodeConstant.NO.equals(resultCode)) {
            return Response.error(message);
        }
        return Response.success();
    }*/

    /**
     * 定时发票作废/红冲
     *
     * @return
     */
    public void invoiceCancel() {
        QueryWrapper<CancelDocDetailEntity> cancelQuery = new QueryWrapper<>();
        cancelQuery.in("cancel_status", CodeConstant.CANCELLIST);
        List<CancelDocDetailEntity> cancelDocDetailEntities = cancelDocDetailMapper.selectList(cancelQuery);
        if (CollectionUtils.isNotEmpty(cancelDocDetailEntities)) {
            List<String> docIds = cancelDocDetailEntities.stream().map(CancelDocDetailEntity::getDocId).collect(Collectors.toList());
            //调用作废红冲接口
            //asyncDocumentService.dealCancelInvoice(docIds);
        }
    }
}
